package com.dk.controller;

import com.alibaba.fastjson.JSONObject;
import com.dk.data.Result;
import com.dk.entity.DtAuctionItem;
import com.dk.entity.DtAuctionOrder;
import com.dk.entity.DtUser;
import com.dk.service.IDtAuctionItemService;
import com.dk.service.impl.DtAuctionItemServiceImpl;
import com.dk.util.IdWorker;
import com.dk.util.JavaMailUtil;
import com.dk.util.JwtUtil;
import com.netflix.zuul.context.RequestContext;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.math.BigDecimal;
import javax.mail.MessagingException;
import javax.servlet.http.HttpServletRequest;
import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.List;

@RestController
@RequestMapping("item")
@Api(value = "拍卖商品管理接口")
public class ItemController {
//    java自带的锁
    private  Lock lock = new ReentrantLock();

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private JavaMailUtil javaMailUtil;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private IDtAuctionItemService itemService;
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("add")
    @ApiOperation(value = "拍卖商品增加")
    //参数类型：paramType body表示@RequestBody接收的参数，path表示路径传参/{xx},query表示@RequestParam接受的参数
    @ApiImplicitParam(name="auctionItem",value = "拍卖商品实体类",required = true,paramType = "body")

    public Result add(@RequestBody DtAuctionItem item){
        long id = idWorker.nextId();
        item.setId(id).setStatus("1").setCreateTime(new Date()).setSellTime(new Date());
        Date date = new Date();
        //当前毫秒值
        long times = date.getTime();
        //3天后的毫秒值、
        long timeafter3days = times+3*24*60*60*1000;

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(timeafter3days);
        Date sellDate = calendar.getTime();
        item.setId(id).setStatus("1").setCreateTime(date).setSellTime(sellDate);
        itemService.add(item);
        return Result.ok();
    }


    @PostMapping("selectByid")
    @ResponseBody
    @ApiOperation("根据拍卖商品的id查询数据 把商品id作key , 价格作value 保存redis , 并返回前台")
    public Result selectById(Long id){
//        根据商品id查询数据
        DtAuctionItem item = itemService.selectById(id);
//        将商品id, 价格 保存redis中,
        redisTemplate.boundValueOps("auction" + id).set(item.getStartPirce());
        redisTemplate.boundValueOps("auction_user").set(item.getUserId());
        return Result.ok().setData(item);
    }

    @PostMapping("addPrice")
    @ResponseBody
    @ApiOperation("买家进行出价 , 根据传递的商品id , 用户Id 查询redis , 获取value,进行判断 , 返回当前的价格")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "商品id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, paramType = "query"),
            @ApiImplicitParam(name = "addPrice", value = "加价", required = true, paramType = "query")
    })
    public Result addPrice (@RequestParam("id") Long id ,@RequestParam("userId") Long userId , @RequestParam("addPrice")String addPrice){

//        获取redis的value与传递的价格相加 , 在与value进行比较 ,数据大的放入redis
        BigDecimal redisPrice = (BigDecimal) redisTemplate.boundValueOps("auction" + id).get();
        Double price = redisPrice.doubleValue();
//         转换
        Double priceDouble = Double.valueOf(addPrice);
//        相加
        Double zongjia = priceDouble + price;
        BigDecimal zong = BigDecimal.valueOf(zongjia);

            lock.lock();
            try {
                if (zongjia > price){
                    redisTemplate.boundValueOps("auction_user").set(userId);
                    redisTemplate.boundValueOps("auction" + id).set(zong);
                    return Result.ok().setData(redisTemplate.boundValueOps("auction" + id).get());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
            return Result.ok().setData(redisTemplate.boundValueOps("auction" + id).get());
    }

    @PostMapping("createOrder")
    @ResponseBody
    @ApiOperation("生成订单表 , 前台传递商品的id")
//    从jwt中获取用户的信息 , 从item表中获取卖家用户
    public Result insertOrder(Long id , HttpServletRequest request){
        String userId = (String) redisTemplate.boundValueOps("auction_user").get();

//        测试使用
        DtUser dtUser = itemService.selectUserById(Long.valueOf(userId));
        String id1 = String.valueOf(dtUser.getId());

        DtAuctionOrder order = new DtAuctionOrder();
        order.setOrderId(id);
        order.setStatus("1");
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date()); //创建时间
        order.setSellerId(id1); //买家id

        order.setReceiverMobile(dtUser.getIsMobileCheck());//手机
        order.setReceiverZipCode(dtUser.getIsEmailCheck());//邮箱
        order.setBuyerNick(dtUser.getNickName());//卖家昵称
        order.setReceiver(dtUser.getNickName()); //买家昵称
        itemService.insertOrder(order);

        return Result.ok();
    }

    @PostMapping("endAuction")
    @ResponseBody
    @ApiOperation("拍卖结束 , 传递商品id , 查询redis中的价格是否变动 , 确认是否流拍 , 获取缓存中用户的id")
    public Result endAuction(Long id){
//        从redis中获取成交用户id
        Long userId = (Long) redisTemplate.boundValueOps("auction_user").get();
        //获取redis中的价格
        BigDecimal redisPrice = (BigDecimal) redisTemplate.boundValueOps("auction" + id).get();
        //转换
        Double doublePrice = redisPrice.doubleValue();

        DtAuctionItem item = itemService.selectById(id);
        //起拍价格
        BigDecimal startPirce = item.getStartPirce();
        double doubleValue = startPirce.doubleValue();
        System.out.println("竞拍价格" + doublePrice);
        System.out.println("起始价格" + startPirce);
        //                  redis中的价格   起拍价格
        if (doublePrice == doubleValue){
//            商品已流拍
            System.out.println(redisPrice);
            //修改商品状态 , 已失效
            item.setStatus("5");
            itemService.updateItemStatus(item);
            System.out.println("流拍");
            //发送短信/邮箱通知委托人商品流拍
            try {
                javaMailUtil.test("拍卖行","你的商品已流拍" , "2669229061@qq.com");
            } catch (MessagingException e) {
                e.printStackTrace();
            }
        }else {
            //商品拍卖成功
            DtAuctionOrder order = itemService.selectOrderById(id);
            //修改item商品的状态
            item.setStatus("6");
            item.setUserId(userId.toString());
            itemService.updateItemStatus(item);

            //设置成交价格
            order.setPayment(redisPrice);
            //设置佣金
            Double d = doublePrice * 0.005;
            order.setUserCommissionPrice(BigDecimal.valueOf(d)); //售买人佣金
            order.setSellerCommissionPrice(BigDecimal.valueOf(d)); //委托人佣金
            order.setUserId(userId.toString());
            System.out.println(d);
            itemService.updateOrder(order);
            //发送邮件通知售买人进行支付,
            try {
                javaMailUtil.test("拍卖行","昨日的姑娘想你了, 你还来不来啊" , "2669229061@qq.com");
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            //发送邮件通知委托人商品以成功拍卖
            try {
                javaMailUtil.test("拍卖行","昨日的姑娘想你了, 你还来不来啊" , "3130261623@qq.com");
            } catch (MessagingException e) {
                e.printStackTrace();
            }
            System.out.println("拍卖成功");
        }
        redisTemplate.delete("auction" + id);
        return Result.ok();
    }

    @PostMapping("oncePrice")
    @ResponseBody
    @ApiOperation("点击出一口价 , 传递买家的id ,和一口价 价格 , 放redis中 , 利用setIfAbsent , 如果有就返回FALSE , 没有就返回TRUE")
    public Result oncePrice(Long id , String oncePrice , Long userId) {
//        redis中的价格
        BigDecimal redisPrice = (BigDecimal) redisTemplate.boundValueOps("auction" + id).get();
        //转换
        Double doublePrice = redisPrice.doubleValue();

        DtAuctionItem item = itemService.selectById(id);
        //一口价的转换
        Double oPrice = Double.valueOf(oncePrice);
//      理想价格的转换
        BigDecimal idealPrice = item.getIdealPrice();
        Double ideaPrice = idealPrice.doubleValue();
        System.out.println(redisTemplate.boundValueOps("auction" + id).get());
        if (!StringUtils.isBlank(oncePrice) && oPrice >= ideaPrice && oPrice > doublePrice) {
            redisTemplate.boundValueOps("auction" + id).set(oPrice);
            redisTemplate.boundValueOps("auction_user").set(userId);
            System.out.println(redisTemplate.boundValueOps("auction" + id).get());
            return Result.ok().setData("你已成为韭菜, 交易成功");
        }
        return Result.ok();
    }
    @PostMapping("update")
    @ApiOperation(value = "审核状态修改")
    //参数类型：paramType body表示@RequestBody接收的参数，path表示路径传参/{xx},query表示@RequestParam接受的参数
    @ApiImplicitParam(name="id",value = "拍卖商品id",required = true,paramType = "query")
    public Result updateStatus(@RequestParam("id") Long id,@RequestParam("status") String status) throws MessagingException {
        itemService.updateStatus(id,status);
        return Result.ok();
    }

    @GetMapping("sellerPay")
    @ApiOperation(value = "商家支付保证金")
    //参数类型：paramType body表示@RequestBody接收的参数，path表示路径传参/{xx},query表示@RequestParam接受的参数
    @ApiImplicitParams({
            @ApiImplicitParam(name="id",value = "拍卖商品id",required = true,paramType = "query"),
            @ApiImplicitParam(name="status",value = "拍卖商品状态",required = true,paramType = "query")
    })
    public String sellerPay(@RequestParam("id") Long id,@RequestParam("status") String status) throws MessagingException {
        if ("2".equals(status)){
          String paystr = itemService.sellerPay(id);
          redisTemplate.boundValueOps("payStyle").set("1");
          return paystr;
        }

        return null;
    }
    @GetMapping("userPay")
    @ApiOperation(value = "买家支付保证金")
    //参数类型：paramType body表示@RequestBody接收的参数，path表示路径传参/{xx},query表示@RequestParam接受的参数
    @ApiImplicitParams({
            @ApiImplicitParam(name="id",value = "拍卖商品id",required = true,paramType = "query"),
            @ApiImplicitParam(name="status",value = "拍卖商品状态",required = true,paramType = "query")
    })
    public String userPay(HttpServletRequest request,@RequestParam("id") Long id,@RequestParam("status") String status) throws MessagingException {
        if ("4".equals(status)){
            String paystr = itemService.userPay(id);
            redisTemplate.boundValueOps("payStyle").set("2");
            //获取用户id
//            String uidStr = isLogined(request);
            String uidStr = "2";
            redisTemplate.boundValueOps("payUserId").set(uidStr);
            return paystr;
        }

        return null;
    }
    @GetMapping("show")
    @ApiOperation(value = "拍卖商品展示")
    public Result show(){
        List<DtAuctionItem> list = itemService.select();
        if (list.size()>0){
            for (DtAuctionItem item : list) {
                redisTemplate.boundHashOps("auctionItem").put(item.getId(),item);
            }
        }

        return Result.ok().setData(list);
    }
    //判断是否登录
    public String isLogined(HttpServletRequest request){

        /** 通过请求头获取token*/
        String authToken = request.getHeader("authToken");
        //获取参数
//        String userName = request.getParameter("userName");
        //校验用户名是否存在，如果不存在，说明用户未登录，不放过(UserDTO)redisTemplate.boundValueOps(authToken).get() == null)
        if(authToken == null || "".equals(authToken)) {
            return null;
        }else {
            try {
                Claims claims = jwtUtil.parseJwt(authToken);
                String userId = claims.getId();
                String subject = claims.getSubject();
                //已登录
                return userId;
            }catch (Exception e){
                return null;
            }
        }
    }




}
